package cloud.alibaba.study.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;

import cloud.alibaba.study.entity.base.ResponseResult;
import cloud.alibaba.study.entity.base.ResponseVo;
import cloud.alibaba.study.entity.order.OrderEntity;
import cloud.alibaba.study.service.order.feign.OrderServiceFeignClient;
import lombok.extern.slf4j.Slf4j;

@RestController
@RequestMapping("/user")
//@RefreshScope//动态获取nacos配置信息
@Slf4j
public class UserController {

	// 获取已注册到Nacos服务端的实例
	@Autowired
	private DiscoveryClient discoveryClient;

	@Value("${server.port}")
	private String serverPort;
	@Value("${spring.application.name}")
	private String springApplicationName;

	@GetMapping(value = "/hello")
	public String hello() {
		return "hello nacos";
	}

	/**
	 * @Title: getNacos @Description: 验证我们当前应用是否注册到Nacos服务 @date: 2021年12月17日
	 * 上午10:50:16 @version: @return @throws
	 */
	@GetMapping(value = "/getNacos")
	private ResponseResult<List<ServiceInstance>> getNacos() {
		ResponseResult<List<ServiceInstance>> res = new ResponseResult<List<ServiceInstance>>();
		List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("m-order-service");
		return res.success(serviceInstanceList);
	}

	@Resource
	private RestTemplate restTemplate;

	@GetMapping(value = "/getOrderList")
	private ResponseResult<Object> getOrderList() {
		ResponseResult<Object> res = new ResponseResult<Object>();
		try {
			res = restTemplate.getForObject("http://m-order-service/order/getOrderList", ResponseResult.class);
		} catch (Exception e) {
			log.error("[UserController][getOrderList] error is," + e.getMessage());
			return res.fail("请求order服务失败：" + e.getMessage());
		}
		return res;
	}

	@GetMapping(value = "/getOrder/{id}")
	public ResponseResult<OrderEntity> getOrder(@PathVariable String id) {
		// 从DiscoveryClient中获取第一个uri进行访问
		List<ServiceInstance> serviceInstances = discoveryClient.getInstances("m-order-service");
		String url = serviceInstances.stream().map(instance -> instance.getUri().toString() + "/order/getOrderInfo")
				.findFirst().orElseThrow(() -> new IllegalArgumentException("找不到实例"));
		// 组装参数
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", id);

		// 远程调用
		ResponseResult<OrderEntity> res = restTemplate.getForObject(url + "/{id}", ResponseResult.class, params);
		return res;
	}

	////////////////////////////////////////////////////// feign客户端调用//////////////////////////////////////////////////////

	@Autowired
	private OrderServiceFeignClient orderFeignClient;

	@GetMapping(value = "/byFeign/getOrderList")
	private ResponseResult<Object> byFeignGetOrderList() {
		ResponseResult<Object> res = new ResponseResult<Object>();
		try {
			res = orderFeignClient.getOrderList();
		} catch (Exception e) {
			e.printStackTrace();
			return res.fail("请求order服务失败：" + e.getMessage());
		}
		return res;
	}

	@GetMapping("/testA")
	public String testA() {
		return "------testA";
	}

//////////////////////////////////////////////////////sentinel限流//////////////////////////////////////////////////////
	/**
	 * 
	 * @Title: helloSentinel   
	 * @Description: 手动配置流控,对该资源限流
	 * @date: 2022年1月5日 下午2:22:02   
	 * @version:
	 * @return          
	 * @throws
	 */
	@SentinelResource(value = "helloSentinel", blockHandler = "blockHandlerHello")
	@GetMapping("/helloSentinel")
	public ResponseVo helloSentinel() {
		return ResponseVo.successMsg("未限流，业务执行成功！");
	}
	
	/**
	 * 
	 * @Title: blockHandlerHello   
	 * @Description: 资源限流后的调用方法
	 * 必须要增加BlockException参数,捕获其异常
	 * @date: 2022年1月5日 下午2:18:37   
	 * @version:
	 * @param e
	 * @return          
	 * @throws
	 */
	public ResponseVo blockHandlerHello(BlockException e) {
		System.out.println("123123123" + e.getMessage());
		return ResponseVo.errorMsg("已限流，降级处理");
	}
	
	
	/**
	 * 
	 * @Title: sentinelDash   
	 * @Description: 基于Sentinel Dashboard流量控制\熔断
	 * @date: 2022年1月5日 下午2:58:31   
	 * @version:
	 * @return          
	 * @throws
	 */
	@GetMapping("/sentinelDash")
	public ResponseVo sentinelDash() {
		return ResponseVo.successMsg("未限流，业务执行成功！");
	}
	
	
	/**
	 * @Title: sentinelDashNacos   
	 * @Description: 配置持久化到Nacos中,从Nacos中推到Sentinel Dash
	 * @date: 2022年1月5日 下午4:56:26   
	 * @version:
	 * @return          
	 * @throws
	 */
	@GetMapping("/sentinelDashNacos")
	public ResponseVo sentinelDashNacos() {
		return ResponseVo.successMsg("未限流，业务执行成功！");
	}
	
}
